package com.pap.rabbitmq.trans.send;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pap.rabbitmq.data.CompleteCorrelationData;
import com.pap.rabbitmq.data.RabbitMetaMessage;
import com.pap.rabbitmq.trans.annotation.TransRabbitMQAnnotation;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @Auther: alexgaoyh
 * @Date: 2018/12/3 16:41
 * @Description:
 */
@Component
public class TransRabbitSender {

    @Autowired
    @Qualifier(value = "transRabbitTemplate")
    RabbitTemplate rabbitTemplate;

    /**
     * 扩展消息的CorrelationData，方便在回调中应用
     */
    public void setCorrelationData(String coordinator) {
        rabbitTemplate.setCorrelationDataPostProcessor(((message, correlationData) ->
                new CompleteCorrelationData(correlationData != null ? correlationData.getId() : null, coordinator)));
    }

    /**
     * 发送MQ消息
     *
     * @param rabbitMetaMessage Rabbit元信息对象，用于存储交换器、队列名、消息体
     * @return 消息ID
     * @throws JsonProcessingException
     */
    public String send(RabbitMetaMessage rabbitMetaMessage) throws JsonProcessingException {
        final String msgId = UUID.randomUUID().toString().replace("-", "");


        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setMessageId(msgId);
                // 设置消息持久化
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return message;
            }
        };

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(rabbitMetaMessage.getPayload());

        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setContentType("application/json");
        Message message = new Message(json.getBytes(), messageProperties);

        try {
            rabbitTemplate.convertAndSend(rabbitMetaMessage.getExchange(), rabbitMetaMessage.getRoutingKey(),
                    message, messagePostProcessor, new CorrelationData(msgId));

            // TODO logger ("发送消息，消息ID:{}", msgId);

            return msgId;
        } catch (AmqpException e) {
            throw new RuntimeException("发送RabbitMQ消息失败！", e);
        }
    }

    //========================== 单元测试部分依赖 ==========================

    /**
     * 执行此方法，会进入到 注解 关联的AOP 中，
     * @return
     */
    @TransRabbitMQAnnotation(exchange = "TRANS_DLX_EXCHANGE", bindingKey = "TRANS_DLX_ROUTING_KEY", bizName = "TRANS_MQ_BIZ",
            dbCoordinator = "transRabbitMQRedisCoordinator")
    public String transSendTest() {
        System.out.println("........trans msg send...........");
        return "{\"id\": \"alexgaoyh\"}";
    }
}
